<?php

namespace App\Business\BLL;

use App\Jobs\SettlementSectPoint;
use App\Models\ChallengeGameDetail;
use App\Models\ChallengeGameLog;
use App\Models\Sect;
use App\Models\WechatUser;
use Illuminate\Support\Facades\Storage;

class SettlementBLL
{
    public function settlement($game)
    {
        $playAPoint = 0;
        $playBPoint = 0;
        if ($game->type == 1) {
            $playA = WechatUser::find($game->play_a);
            $playB = WechatUser::find($game->play_b);
            $matchPoint = config('set.match_point');
            $playAPoint = UserDaliyPointBLL::getUserPoint($game->play_a, $matchPoint);
            $playBPoint = UserDaliyPointBLL::getUserPoint($game->play_b, $matchPoint);
        } else {
            $playA = Sect::find($game->play_a);
            $playB = Sect::find($game->play_a);
            $matchPoint = config('set.sect_match_point');
            $playAPoint = $matchPoint;
            $playBPoint = $matchPoint;
        }
        //记录数据change_score
        $log = new ChallengeGameLog();
        $log->game_id = $game->id;
        $log->type = $game->type;
        $log->play_a = $game->play_a;
        $log->play_b = $game->play_b;
        $log->score_a = $playA->score;
        $log->score_b = $playB->score;
        $log->win_a = $playA->winning_streak;
        $log->win_b = $playB->winning_streak;
        $log->max_win_a = $playA->max_winning_streak;
        $log->max_win_b = $playB->max_winning_streak;

        //活跃
        $playA->point = $playA->point + $playAPoint;
        $playB->point = $playB->point + $playBPoint;

        //积分
        $log->change_score = $this->getScore($game, $playA, $playB);

        $playA->score = $playA->score > 0 ? $playA->score : 0;
        $playB->score = $playB->score > 0 ? $playB->score : 0;
        //连胜
        if ($game->score_a > $game->score_b) {
            $playA->winning_streak = $playA->winning_streak + 1;
            $playB->winning_streak = 0;
            $playA->max_winning_streak = $playA->winning_streak > $playA->max_winning_streak ? $playA->winning_streak : $playA->max_winning_streak;
        } else {
            $playA->winning_streak = 0;
            $playB->winning_streak = $playB->winning_streak + 1;
            $playB->max_winning_streak = $playB->winning_streak > $playB->max_winning_streak ? $playB->winning_streak : $playB->max_winning_streak;
        }
        $playA->save();
        $playB->save();
        $log->save();
        if ($game->type == 1) {
            //单人比赛，门派增加活跃
            $sectMatchPoint = config('set.sect_match_point');
            // dispatch((new SettlementSectPoint($playA->id, $sectMatchPoint)));
            // dispatch((new SettlementSectPoint($playB->id, $sectMatchPoint)));
            SettlementSectPoint::dispatch($playA->id, $sectMatchPoint);
            SettlementSectPoint::dispatch($playB->id, $sectMatchPoint);
        }
        return ['status' => true, 'msg' => '更新成功'];
    }

    public function resettlement($game, $oldScoreA, $oldScoreB)
    {
        //清除小分和详情
        $detail = ChallengeGameDetail::where('game_id', $game->id)->first();
        if ($detail) {
            $detail->score = null;
            if ($detail->desc) {
                $fileObj = \json_decode($detail->desc, true);
                //删除存储空间中文件
                $disk = Storage::disk('qiniu');
                $disk->delete($fileObj['file']);
                $detail->desc = null;
            }
            $detail->save();
        }

        if ($game->score_a > $game->score_b === $oldScoreA > $oldScoreB) {
            //比分错误，胜负正确
            return ['status' => true, 'msg' => '更新成功'];
        }

        //重算积分
        $log = ChallengeGameLog::where('game_id', $game->id)->first();

        if ($game->type == 1) {
            $playA = WechatUser::find($game->play_a);
            $playB = WechatUser::find($game->play_b);
        } else {
            $playA = Sect::find($game->play_a);
            $playB = Sect::find($game->play_a);
        }
        //重置数据
        $playA->score = $log->score_a;
        $playB->score = $log->score_b;
        $playA->winning_streak = $log->win_a;
        $playB->winning_streak = $log->win_b;
        $playA->max_winning_streak = $log->max_win_a;
        $playB->max_winning_streak = $log->max_win_b;

        //积分计算
        $log->change_score = $this->getScore($game, $playA, $playB);

        $playA->score = $playA->score > 0 ? $playA->score : 0;
        $playB->score = $playB->score > 0 ? $playB->score : 0;
        //连胜
        if ($game->score_a > $game->score_b) {
            $playA->winning_streak = $playA->winning_streak + 1;
            $playB->winning_streak = 0;
            $playA->max_winning_streak = $playA->winning_streak > $playA->max_winning_streak ? $playA->winning_streak : $playA->max_winning_streak;
        } else {
            $playA->winning_streak = 0;
            $playB->winning_streak = $playB->winning_streak + 1;
            $playB->max_winning_streak = $playB->winning_streak > $playB->max_winning_streak ? $playB->winning_streak : $playB->max_winning_streak;
        }

        $playA->save();
        $playB->save();
        $log->save();
        return ['status' => true, 'msg' => '更新成功'];
    }

    private function getScore($game, $playA, $playB)
    {
        $scoreArray = $this->scoreRange($playA->score, $playB->score);
        $changeScore = 0;
        if ($game->score_a > $game->score_b) {
            //A胜，B负
            if ($playA->score > $playB->score) {
                $playA->score = $playA->score + $scoreArray[0];
                $playB->score = $playB->score - $scoreArray[0];
                $changeScore = $scoreArray[0];
            } else {
                $playA->score = $playA->score + $scoreArray[1];
                $playB->score = $playB->score - $scoreArray[1];
                $changeScore = $scoreArray[1];
            }
        } else {
            //A.负，B.胜
            if ($playA->score > $playB->score) {
                $playA->score = $playA->score - $scoreArray[1];
                $playB->score = $playB->score + $scoreArray[1];
                $changeScore = $scoreArray[1];
            } else {
                $playA->score = $playA->score - $scoreArray[0];
                $playB->score = $playB->score + $scoreArray[0];
                $changeScore = $scoreArray[0];
            }
        }
        return $changeScore;
    }

    private function scoreRange($scoreA, $scoreB)
    {
        $diff = abs($scoreA - $scoreB);
        $rules = config('set.score_rule');
        $ret = [0, 0];
        foreach ($rules as $vo) {
            if ($vo[1] >= $diff) {
                $ret = [$vo[2], $vo[3]];
                break;
            }
        }
        return $ret;
    }
}
